#include <stdio.h>
#include <stdlib.h>
#include <regex.h>

// 输出字符串中指定范围内的字符
void print_substr(const char* s, size_t __start, size_t __end);

int main (int argc, char** argv)
{
    int id, n, i;
    // 错误信息长度
    size_t err_buf_size;
    // 正则编译缓存
    regex_t pat_buf;
    // 错误信息字符串
    char *err_buf = NULL;
    // 记录分组匹配数据
    regmatch_t *pmatch = NULL;

    // 正则表达式
    char* pat_str = "([0-9]+\\.[0-9]+)";
    // 被匹配字符串
    char* str = "   0.1234  1.2345  2.34567     8 9   10.111213";

    // 编译正则表达式
    id = regcomp(&pat_buf, pat_str, REG_EXTENDED);
    if(id != 0)
    {
        // 计算错误信息长度
        err_buf_size = regerror(id, &pat_buf, NULL, 0);

        // 分配内存
        err_buf=(char*)malloc(err_buf_size * sizeof(char));
        if(err_buf == NULL)
        {
            printf("not enough memory for err_buf!\n");
            regfree(&pat_buf);
            exit(EXIT_FAILURE);
        };

        // 提取错误信息并输出
        regerror(id, &pat_buf, err_buf, err_buf_size);
        fprintf(stderr, "Regex compilation error: %s\n", err_buf);

        // 释放空间
        regfree(&pat_buf);
        free(err_buf);
        exit(EXIT_FAILURE);
    };

    // 分配匹配位置结果结构体数组(匹配寄存器数组)
    pmatch = (regmatch_t*)malloc((pat_buf.re_nsub + 1) * sizeof(regmatch_t));
    if(pmatch == NULL)
    {
        printf("not enough memory for pmatch!\n");
        regfree(&pat_buf);
        exit(EXIT_FAILURE);
    }

    // 正则匹配，返回0表示匹配成功
    n = regexec(&pat_buf, str, pat_buf.re_nsub + 1, pmatch, 0);
    if(n != 0)
    {
        printf("Nothing matched with %s\n", str);

        regfree(&pat_buf);
        free(pmatch);

        exit(0);
    };

    // 找到匹配，输出
    for (i = 0; i <= pat_buf.re_nsub; i++)
    {
        printf("group %d : [", i);
        printf("%d, %d", pmatch[i].rm_so, pmatch[i].rm_eo);
        printf(")-->");
        print_substr(str, pmatch[i].rm_so, pmatch[i].rm_eo);
    }

    // 释放空间
    regfree(&pat_buf);
    free(pmatch);

    return 0;
}

/* 输出字符串中指定范围的字符 */
void print_substr(const char* s, size_t __start, size_t __end)
{
    int i;

    if(s)
    {
        for(i = __start; i < __end; ++i)
        {
            putchar(s[i]);
        }
    }

    putchar('\n');
}
